/*
* JavaScript Validator.prototype.Library v1.1, by Sergey Shuchkin (shuchkin@mail.ru), 2007
* Install:
* <script type="text/javascript" src="validator.js" lang="ru"></script>
* ...
* <form ... class="autoCheck">
* <input type="text" name="email" class="isEmail">
* ...
* </form>
*
* Changes:
* 1.1.3 10/12/2007
* + added isCreditCardNumber (isCCNum)
* 1.1.2 09/19/2007
* + added "video" for fileExt
* - Fixed "FIELDSET" element
* 
* 1.1.1 09/18/2007
* + String.prototype used now
* 1.1 09/17/2007
* + centered DHTML layer for error message
* + support "vlang" attribute from script tag
* 1.0 Initial release
*/
Validator = function () {
  this.v = '1.1.3';
  // Get last script element
  var objContainer = document.body;
  if (!objContainer) {
    objContainer = document.getElementsByTagName("head")[0];
    if (!objContainer)  objContainer = document;
  }
  this.objScript = objContainer.lastChild;
  // Get path
  this.path = "";
  var strSrc = this.objScript.getAttribute("src");
  if (strSrc) {
    var arrTokens = strSrc.split("/");
    // Remove last token
    arrTokens = arrTokens.slice(0, -1);
    if (arrTokens.length)
	  this.path = arrTokens.join("/") + "/";
  }
  this.lang = {}; // will be load

  this.fileExt = {
    images : "jpg,jpeg,gif,png",
    docs : "doc,pdf,rtf,htm,html,zip,rar,7z,gz,tar",
	video: "avi,mpg,mpeg,flv,mov"
  };
  this.form = false;
  this.error = false;
  this.errors = [];
  this.loaded = false;
  // Load lang
  this.language = "en";
  this.lang = {about: "Validator v"+this.v};
  if (typeof validator_lang != "undefined") this.language = validator_lang;
  else if (typeof this.objScript.attributes['lang'] != "undefined") {
    var s = this.objScript.attributes['lang'].value;
    if (s.length > 0) this.language = s;
  }
  var filename = this.path+'langs/' + this.language +'.xml';
  var xml = this.ajax(filename);
  if (xml.length == 0) {
    alert('validator.js: language not found '+filename);
  } else {
    axml = xml.split("\n");
	for (var i=0; i<axml.length; i++) {
      if (r = axml[i].match(/<about>(.*)<\/about>/)) this._about = r[1].replace(/\\n/g,'\n');
      if (r = axml[i].match(/<e_([^>]+)>(.*)<\/e_\1>/)) this.lang['e_'+r[1]] = r[2].replace(/\\n/g,'\n');
	}
  }
  //alert(objL.src);
  //document.write('<s'+'cript type="text/javascript" src="'+this.path+'langs/' + this.language +'.js"></s' + 'cript>');

  this.onLoad = function() {
    for (var i=0; i < document.forms.length; i++) {
      var frm = document.forms[i];
      if (frm.className.search(/autoCheck|auto_check/i) != -1 || typeof(frm.elements['_validator_']) != "undefined") {
        if (typeof(frm.onsubmit) != "undefined") {
          frm.oldonsubmit = frm.onsubmit;
        }			
        frm.onsubmit = function() {
          return validator.checkForm(this);
        };
      }
    }
    this.loaded = true;
  }

  // Add onload handler
  if (window.addEventListener)
    window.addEventListener("load", this.onLoad, false);
  else if (window.attachEvent) 
    window.attachEvent("onload", this.onLoad); 
  else window.onload = this.addHandlers;
}
// Main checking method
Validator.prototype.checkForm = function(frm) {
  if (this.submitted) {
    alert(this.lang.e_sub);
    return false;
  }
  if (typeof(frm) == 'string') frm = document.getElementById(frm);
  if (!frm) return false;
  this.form = frm;
  this.vfields = [];
  this.resetError();
  // php validator config support
  if (typeof(frm.elements['_validator_']) != "undefined") {
    var a = frm.elements['_validator_'].value.split(";;");
	var b = [];
	for (var i = 0; i<a.length; i++) {
		b = a[i].split("::"); // name::title::vtags
		if (b.length == 3) this.vfields[b[0]] = {title: b[1], tags: b[2]};
		else this.vfields[b[0]] = {title: null, tags: b[1]};
	}
  }
  var _cache = [];
  var _ajax_cache = [];
  var _focused = false;
  // Main control
  var el,el_type,is_input,cn,name;
  for (var i=0; i < this.form.elements.length; i++) {
    el = this.form.elements[i];
	if (el.tagName == "FIELDSET") continue;
	is_input = el.tagName.toUpperCase() == "INPUT";
	el_type = (is_input) ? el.type.toUpperCase() : "";    
    cn = el.className;	
    name = el.name;
    if (el.title && el.title.length > 0) name = el.title;
	if (typeof(this.vfields[el.name]) != "undefined") {
      if (this.vfields[el.name].title != null) name = this.vfields[el.name].title;
	  cn = this.vfields[el.name].tags;
	}
	//alert(name); alert(el.tagName);
	name = name.UCWords();
	
	// First checking REQUIRED
    var skip_req = false; // for debug
	
	if (cn.search(/req|required/i) != -1 && !skip_req) {
      // check INPUT RADIO
	  if (is_input && (el_type == "TEXT" || el_type == "PASSWORD")) {
		if (el.value == "") {
		  this.error = true;
		  this.errors[this.errors.length] = this.lang.e_req.replace(/%s/, name);
		}		
	  }
      if (is_input && el_type == "RADIO") {
        var in_cache = false;
        for (var j=0; j < _cache.length; j++) if (name == _cache[j]) {in_cache = true; break}
        if (!in_cache) {
          _cache.push(el.name);
          this.checkRadio(el.name,this.lang.e_req.replace(/%s/,name));
        }
      }
	  if (is_input && el_type == "FILE") {
		if (el.value == "") {
		  this.setError(this.lang.e_fil.replace(/%s/,name));
		}
	  }
	  // check SELECT field
      if (el.tagName.toUpperCase() == "SELECT") {
        var def = "";
        if (r = cn.match(/(def|default)=([^\s]+)/i)) def = r[2];
        this.checkSelect(el.name,def,this.lang.e_sel.replace(/%s/,name));
      }
      if (el.tagName.toUpperCase() == "TEXTAREA") {
		if (el.value == "") {
		  this.setError(this.lang.e_req.replace(/%s/,name));
		}		
      }
    }
	// check extended types
    if (is_input) {
      if ((el_type == "TEXT" || el_type == "PASSWORD") && el.value != "") {
		var value = el.value;
		
		// check input (MINLEN)
        if (r = cn.match(/minlen\=(\d+)/i)) {
          this.checkInput(el.name,r[1],this.lang.e_len.replace(/%s/,name).replace(/%d/,r[1]));
        }
		// check input (MAXLEN)
        if (r = cn.match(/maxlen\=(\d+)/i)) {
          this.checkInputSize(el.name,r[1],this.lang.e_siz.replace(/%s/,name).replace(/%d/,r[1]));
        }
		// check INTEGER
		if (cn.search(/isInt[^_]|isInteger|is_int[^_]|is_integer/i) != -1) {		  
		  min_value = null; max_value = null;
		  if (r = cn.match(/min\=(\-?\d+)/i)) min_value = parseInt(r[1]);
		  if (r = cn.match(/max\=(\-?\d+)/i)) max_value = parseInt(r[1]);
		  s = '.';
		  //alert(min_value+" "+max_value);
		  if (min_value !== null) s = this.lang.e_int_min.replace(/%s/,min_value);
		  if (max_value !== null) s = this.lang.e_int_max.replace(/%s/,max_value);
		  if (min_value !== null && max_value !== null)
		    s = this.lang.e_int_rng.replace(/%min/,min_value).replace(/%max/,max_value);
		  
		  this.checkInt(el.name,min_value,max_value,this.lang.e_int.replace(/%s/,name) + s);
		}
		// check Float
		if (cn.search(/isFloat|is_float/i) != -1) {
		  this.checkFloat(el.name, this.lang.e_flt.replace(/%s/,name));
		}
		// check EMAIL
        if (cn.search(/isEmail|is_email/i) != -1) {
          this.checkEmail(el.name, this.lang.e_val.replace(/%s/,name));
        }
		// check URL
		if (cn.search(/isURL|is_url/i) != -1) {
		  this.checkURL(el.name, this.lang.e_url.replace(/%s/,name));
		}
		// check US PHONE
		if (cn.search(/isUSPhone|is_us_phone/i) != -1) {
		  this.checkUSPhone(el.name, this.lang.e_uph.replace(/%s/,name));
		}
		// check INTERANTIONAL PHONE
		if (cn.search(/isIntPhone|is_int_phone/i) != -1) {
		  this.checkIntPhone(el.name, this.lang.e_iph.replace(/%s/,name));
		}
		// check US ZIP
		if (cn.search(/isUSZip|isZip|is_us_zip|is_zip/i) != -1) {
		  this.checkUSZip(el.name, this.lang.e_uzp.replace(/%s/,name));
		}
		// check DATE
		if (cn.search(/isDate|is_date/i) != -1) {
		  var format = this.lang.e_df;
		  if (r = cn.match(/(isDate|is_date)=([^\s]+)/i)) format = r[2];
		  if (r = cn.match(/format=([^\s]+)/i)) format = r[1];
		  var s = format.replace(/%/g,'').replace(/m/,'mm').replace(/d/,'dd').replace(/y/,'yy').replace(/Y/,'YYYY');
		  this.checkDate(el.name, format, this.lang.e_dat.replace(/%s/,name).replace(/%f/, s));
        }
        // check PASSWORD
        if (cn.search(/(isPass|isPassword|is_pass|is_password)/i) != -1) {
          var pass_conf = (r = cn.match(/(passConf|pass_conf)=([^\s]+)/i)) ? r[2] : el.name;
          var pass_conf_title = this.getTitle(pass_conf);
          var pass_len = (r = cn.match(/(passLen|pass_len)=([^\s]+)/i)) ? r[2] : 5;
          var pass_chars = (r = cn.match(/(passChars|pass_chars)=([^\s]+)/i)) ? r[2] : '0-9a-zA-Z\-_';
          var m1 = this.lang.e_len.replace(/%s/,name).replace(/%d/,pass_len);
          var m2 = this.lang.e_pwd.replace(/%conf/,pass_conf_title).replace(/%pass/,name);
          var m3 = this.lang.e_pwc.replace(/%s/,name).replace(/%chars/,pass_chars);
          //alert(pass_len);
          this.checkPassword(el.name,pass_conf,pass_len,m1,m2,pass_chars,m3);
		}
        // check REGEX
        if (r = cn.match(/regex=([^\s]+)/i)) {
		  this.checkRegex(el.name, r[1], this.lang.e_val.replace(/%s/,name));
		}
		// AJAX validation
		if (cn.search(/isAjax|is_ajax/i) != -1) {
	      var _url = "";
          if (r = cn.match(/(isAjax|is_ajax|ajax)=([^\s]+)/i)) { _url = r[2]; }
          if (r = cn.match(/url=([^\s]+)/i)) { _url = r[1]; }
		  _ajax_cache[_ajax_cache.length] =  {name: el.name, url: _url, msg: this.lang.e_val.replace(/%s/,name)};
        }
		if (r = cn.match(/(isFile|is_file|ext|extensions)=([^\s]+)/i)) {
          var ext = r[2];
          if (this.fileExt[ext]) ext = this.fileExt[ext];
          this.checkFile(el.name, ext, this.lang.e_ext.replace(/%s/,name).replace(/%f/,ext));
        }
      };
	  // check INPUT FILE
      if (el_type == "FILE" && el.value != "") {		
        if (r = cn.match(/(isFile|is_file|ext|extensions)=([^\s]+)/i)) {
          var ext = r[2];
          if (this.fileExt[ext]) ext = this.fileExt[ext];
          this.checkFile(el.name, ext, this.lang.e_ext.replace(/%s/,name).replace(/%f/,ext));
        }
      }
	}
    // check Credit Card, must be present in credit card type dropdown menu
    // isCC ccN=num_field_id ccM=exp_month_field_id ccY=exp_year_field_id
    if ((el.tagName.toUpperCase() == "SELECT") && (r = cn.match(/(isCreditCard|isCC)\s(ccNum|ccN)=([^\s]+)\s(ccExpMonth|ccM)=([^\s]+)\s(ccExpYear|ccY)=([^\s]+)/i))) {
      var tt = this.getTitle(el.name);
      var n = r[3];
      var tn = this.getTitle(n);
      var m = r[5];
      var tm = this.getTitle(m);
      var y = r[7];
      var ty = this.getTitle(y);
      this.checkCreditCard(el.name,n,m,y,this.lang.e_cct.replace(/%s/,tt),this.lang.e_ccl.replace(/%s/,tn),this.lang.e_cce.replace(/%s/,tm+' / '+ty),this.lang.e_ccn.replace(/%s/,tn));
	}
    if (this.error && !_focused) { el.focus(); _focused = true; }
  }
  if (typeof(this.form.oldonsubmit) == "function") this.error = this.form.oldonsubmit;
  // AJAX check, at last....
  if (!this.error) for (var i = 0; i<_ajax_cache.length; i++) this.checkAjax(_ajax_cache[i].name, _ajax_cache[i].url, _ajax_cache[i].msg);
  
  if (this.error) {
	this.showError();
    return false;
  } else {
    this.submitted = true;
    return true;
  }
}
Validator.prototype.getTitle = function(name) {
  if (field = this.findField(name)) {
    if (typeof(field.title) != "undefined" && field.title.length > 0) return field.title;
    else return field.name.UCWords();
  }
  return name;
}
Validator.prototype.resetError = function() { this.error = false; this.errors = []; }
Validator.prototype.setError = function(err) { this.error = true; this.errors[this.errors.length] = err; }
Validator.prototype.getError = function() { return this.error ? this.lang.e_msg+"\n\n* "+this.errors.join("\n* ") : false; }

Validator.prototype.getErrorLayer = function() {
  var el = document.getElementById("error");
  if (el == null) el = document.getElementById("divError");
  if (el == null) {
    // Create DHTML Layer
    var layer = document.createElement("DIV");
	layer.id = "divError";
    with (layer.style) {
      display = "none";
      position = "absolute"
      width = "400px";
      height = "250px";
      //overflow = "auto";
      padding = "5px";
	  borderStyle = "solid";
      borderWidth = "2px";
      borderLeftColor = "#EEEBE3";
      borderTopColor = "#EEEBE3";
      borderRightColor = "#C4B899";
      borderBottomColor = "#C4B899";
  	  backgroundColor = "#F9F9D9";
	  backgroundImage = "url("+this.path+"img/bg.gif)";
	  backgroundRepeat = "repeat-x";
      backgroundPosition = "top";
      fontSize = "11px";
      fontFamily = "Tahoma";
    }
    if (document.getElementsByTagName("body") != null) document.getElementsByTagName("body")[0].appendChild(layer);
	el = document.getElementById("divError");
  }
  return el;
}

Validator.prototype.showError = function() { // for inline errors <div id="errors" style="display: none">Errors</div>
  if (!this.error) {
    this.submitted = true;
    return true;
  } else {
    var elError = this.getErrorLayer();
    if (elError != null) {
      var err = "<div><img src=\""+this.path+"img/e.gif\" style=\"float:left; border-width: 0px; margin-right: 5px; margin-top: 3px\"/>";
	  err += "<img style=\"float: right\" src=\""+this.path+"img/x.gif\"";
	  err += " onmouseover=\"this.src='"+this.path+"img/x-over.gif'\"";
	  err += " onmouseout=\"this.src='"+this.path+"img/x.gif'\" value=\"close\" title=\"close\"";
	  err += " onclick=\"document.getElementById('"+elError.id+"').style.display='none'; return false\" />";
	  err += "<b>"+this.lang.e_msg.replace("\n","<br/>")+"</b></div>";
	  err += "<div style=\"height: 185px; overflow: auto; margin-top: 5px; \">";
      err += "<ol style=\"color: red;\"><li>"+this.errors.join("</li>\n<li>")+"</li>";
	  //for (i = 0; i < 100; i++) err += "<li>"+i+"-test item</li>";
      err += "</ol>";
	  err += "</div>";
	  err += "<div align=\"center\"><input type=\"button\" value=\"Ok\" onclick=\"document.getElementById('"+elError.id+"').style.display='none';\" style=\"width: 75px; float: none\" /></div>";
	  //alert(err);
      elError.innerHTML = err;
      elError.style.display = "";
      moveToCenter(elError);
    } else {
      alert(this.getError());
    }
    this.submitted = false;
    return false;
  }
}
Validator.prototype.findField = function(name) {
  var obj = false;
  if (typeof(this.form) != "undefined" && typeof(this.form.elements[name]) != "undefined") obj = this.form.elements[name];
  if (!obj && document.getElementById(name) != null) obj = document.getElementById(name);
  if (obj && typeof(obj.type) != "undefined" && obj.type != "hidden" && typeof(obj.value) != "undefined") return obj;
  return false;
}
Validator.prototype.checkInput = function(field_name, field_size, message) {
  if (field = this.findField) {
    if (field.value == '' || field.value.length < field_size) {
      this.setError(message);
    }
  }
}
Validator.prototype.checkInputSize = function(field_name, field_size, message) {
  if (field = this.findField(field_name)) {
    if (field.value.length > field_size) {
      this.setErrorMessage(message);
    }
  }
}
Validator.prototype.checkRegex = function(field_name, regex, message) {
  if (field = this.findField(field_name)) {
    if (r = regex.match(/\/(.*)\/(.*)/)) {
      regex = r[1]; flags = r[2];
    } else {
      flags = "";
    }
    if (field.value.search(new RegExp(regex,flags)) == -1) {
      this.setError(message);
    }
  }
}
Validator.prototype.checkInt = function(field_name, min_value, max_value, message) {
  if (field = this.findField(field_name)) {
    if (field.value.search(/^\-?\d+$/) == -1 || (min_value !== null && field.value < min_value) || (max_value !== null && field.value > max_value)) {
      this.setError(message);
    }
  }
}
Validator.prototype.checkFloat = function(field_name, message) {
  if (field = this.findField(field_name)) {
	var parsed = parseFloat(field.value);
    if (field.value != parsed) {
      this.setError(message);
    }
  }
}
Validator.prototype.checkRadio = function(field_name, message) {
  var isChecked = false;
  if (radio = this.findField(field_name)) {
    for (var i=0; i<radio.length; i++) {
      if (radio[i].checked == true) {
        isChecked = true;
        break;
      }
    }
    if (isChecked == false) {
      this.setError(message);
    }
  }
}
Validator.prototype.checkSelect = function(field_name, field_default, message) {
  if (field = this.findField(field_name)) {
    if (field.value == field_default) {
      this.setError(message);
    }
  }
}
Validator.prototype.checkFile = function(field_name, ext, message) {
  if (field = this.findField(field_name)) {
	if (this.fileExt[ext]) ext = this.fileExt[ext];
    var regex = new RegExp("(" + ext.replace(/,/g,"|") + ")$","i");
    if (field.value.search(regex) == -1) {
      this.setError(message);
    }
  }
}
Validator.prototype.checkPassword = function(field_name_1, field_name_2, field_size, message_1, message_2, chars, message_3) {
  if ((pfield = this.findField(field_name_1)) && (cfield = this.findField(field_name_2))) {
    var password = pfield.value;
    var confirmation = cfield.value;

    if (password == '' || password.length < field_size) {
      this.setError(message_1);
    } else if (password != confirmation) {
      this.setError(message_2);
    } else if (chars && message_3 && password.search(new RegExp("^["+chars+"]+$")) == -1) {
	  this.setError(message_3);
	}
  }
}
Validator.prototype.checkPasswordNew = function(field_name_1, field_name_2, field_name_3, field_size, message_1, message_2, message_3) {
  if ((password_current = this.findField(field_name_1)) && (password_new = this.findField(field_name_2)) && (password_conf = this.findField(field_name_3))) {
    if (password_current.value == '' || password_current.value.length < field_size) {
      this.setError(message_1);
    } else if (password_new.value == '' || password_new.value.length < field_size) {
      this.setError(message_2);
    } else if (password_new.value != password_conf.value) {
      this.setError(message_3);
    }
  }
}
Validator.prototype.checkEmail = function(field_name,message) {
  //regex = /^[A-z0-9][\w.-]*@[A-z0-9][\w\-\.]+\.[A-z0-9]{2,6}$/;
  if (field = this.findField(field_name)) {
    if (!field.value.isEmail()) {
      this.setError(message);
    }
  }
}
Validator.prototype.checkURL = function(field_name, message) {
  if (field = this.findField(field_name)) {
    if (!field.value.isURL()) {
      this.setError(message);
    }
  }	
}
Validator.prototype.checkDate = function(field_name, fmt, message) {
  if (field = this.findField(field_name)) {
    if (!field.value.isDate(fmt)) {
      this.setError(message);
    }
  }
}
// xxx xxx-xxxx
Validator.prototype.checkUSPhone = function(field_name, message) {
  if (field = this.findField(field_name)) {
    if (!field.value.isUSPhone()) {
      this.setError(message);
    }
  }
}
//+x xxx xxx-xxxx
Validator.prototype.checkIntPhone = function(field_name, message) {
  if (field = this.findField(field_name)) {
    if (!field.value.isIntPhone()) {
      this.setError(message);
    }
  }
}
// xxxxx or xxxxx-xxxx
Validator.prototype.checkUSZip = function(field_name, message) {
  if (field = this.findField(field_name)) {
    if (!field.value.isUSZip()) {
      this.setError(message);
    }
  }
}
// Credit Card number
Validator.prototype.checkCreditCard = function(cc_type_name,cc_num_name,cc_exp_month_name,cc_exp_year_name,msg_type,msg_length,msg_expiration,msg_number) {
  if ((cc_type = this.findField(cc_type_name)) &&
    (cc_num = this.findField(cc_num_name)) &&
    (cc_exp_month = this.findField(cc_exp_month_name)) &&
    (cc_exp_year = this.findField(cc_exp_year_name))
  ) {
    if (this._getCardInfo(cc_type.value)) {	
      if (this._checkCardLenght(cc_num.value, cc_type.value)) {
        if (this._checkCardExpireDate(cc_exp_month.value, cc_exp_year.value)) {
          if (this._checkCardNumber(cc_num.value, cc_type.value) && this._checkCardNumberMod10(cc_num.value)) {
            return;
          } else {
            this.setError(msg_number);
          }
        } else {
          this.setError(msg_expiration);
        }
      } else {
        this.setError(msg_length);
      }
    } else {
      this.setError(msg_type);
    }
  }
}
Validator.prototype._getCardInfo = function(cardType) {
	if ((cardType = cardType.toUpperCase()).length != 1) return false;
	var cards = {
		V: {type: 'V', name: 'Visa', start: '4', length: '13,16'},
		M: {type: 'M', name: 'MasterCard', start: '51,52,53,54,55', length: '16'},
		D: {type: 'D', name: 'DiscoverCard', start: '6011', length: '16'},
		A: {type: 'A', name: 'AmericanExpress', start: '34,37', length:'15'},
		C: {type: 'C', name: 'DinersClub', start: '30,36,38', length: '14'},
		J: {type: 'J', name: 'JCBCard', start: '3088,3096,3112,3158,3337,3528', length: '16'},
		E: {type: 'E', name: 'enRouteCard', start: '2014,2149', length: '15'}
	};
	if (typeof(cards[cardType]) != "undefined")
		return cards[cardType];
	else
		return false;
}
Validator.prototype._checkCardLenght = function(cardNumber,cardType) {
	checkSize = false;
	if (cardInfo = this._getCardInfo(cardType)) {
		arraySize = cardInfo['length'].split(",");
		for (var i = 0; i<arraySize.length; i++) {
			if (cardNumber.length == arraySize[i]) {
				checkSize = true;
				break;
			}
		}
	}
	return checkSize;
}
Validator.prototype._checkCardNumber = function(cardNumber,cardType) {
	checkNumber = false;

	if (cardInfo = this._getCardInfo(cardType)) {
		arrayStart = cardInfo['start'].split(",");
		for (var i = 0; i<arrayStart.length; i++) {
			if (cardNumber.substr(0,arrayStart[i].length) == arrayStart[i]) {
				checkNumber = true;
				break;
			}
		}
	}		
	return checkNumber;
}
Validator.prototype._checkCardNumberMod10 = function(cardNumber) {
  return cardNumber.isCreditCardNumber();
}
Validator.prototype._checkCardExpireDate = function(expireMonth,expireYear) {
  if ((expireMonth == "00" && expireYear == "00") || expireMonth == "" || expireYear == "") return false;
  var c = new Date();
  var cy = c.getFullYear();
  var cm = c.getMonth();
  if ((parseInt(expireYear) > cy) || ((parseInt(expireMonth) > cm) && (parseInt(expireYear) == cy))) return true;
  return false;
}
// Ajax validation
Validator.prototype.checkAjax = function(field_name, url, message) {
 try {
  if (field = this.findField(field_name)) {
	if (typeof(url) == "undefined" || url == "") {url = window.location.href}
	if (url.indexOf("?") != -1) url += "&validator_ajax=1&"; else url += "?validator_ajax=1&";
	url += field_name+"="+escape(field.value)+"&rnd="+Math.random();
	//alert(url);
	var result = this.ajax(url);
    if (typeof(result) == "object" && !result.success) {
	  //var msg = this.lang.e_val.replace(/%s/, field_name);
	  if (typeof(result.error) == "string") message = result.error;
      this.setError(message);
    }
  }
 } catch(e) {
   alert(e);
 }
}
// XMLHttpRequest
Validator.prototype.ajax = function(url) {
  var objRequest = null;
  try {
    if (typeof XMLHttpRequest != 'undefined') {
      objRequest = new XMLHttpRequest();
    } else if (typeof ActiveXObject != 'undefined') {
      objRequest = new ActiveXObject(this.getNameOfActiveX());
    }
    if (!objRequest) return false;
    objRequest.open("GET", url, false);
    objRequest.send("");
    //alert("Response code was: " + objRequest.status);
    if (objRequest.status == 200 || objRequest.status == 304 || (location.protocol == 'file:' && !objRequest.status)) {
      if (objRequest.responseText && objRequest.responseText.length > 0) {
        //alert(objRequest.responseText);
        var obj = null;
		if (objRequest.responseText.charAt(0) == '{') {
          eval("obj = "+objRequest.responseText+";")
          return obj; // JSON {success : true/false, error : ""}
		} else {
          return objRequest.responseText;
		}
      }
    }
  } catch(e) {
	alert(e);
  }
  return {success: true};
}
Validator.prototype.getNameOfActiveX = function() {
  var v = ['Msxml2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP','Microsoft.XMLHTTP'];
  for (var i = 0; i < v.length; i++) {
    try {
      var objDocument = new ActiveXObject(v[i]);
      // If it gets to this point, the string worked
      return v[i];
    } catch (e) {};
  }
  return null;
}

/*---------------- Collection of validate functions ----------------*/

/*
* Returns true if domain is valid domain name or IP-address
* @param domain - [string] value to test
*/
String.prototype.isDomain = function(){
	var domain = this.toString();
	if(typeof(domain) != 'string'){
		return false;
	}
	for (i = 0; i < domain.length; i++){
		if (domain.charCodeAt(i) > 127){
			return false;
		}
	}
	var ipDigit = "(0?0?\\d|[01]?\\d\\d|2[0-4]\\d|25[0-6])";
	var ipRE = new RegExp("^" + ipDigit + "\\." + ipDigit + "\\." + ipDigit + "\\." + ipDigit + "$");
	if (ipRE.test(domain)) {
		return true;
	}
	var domains = domain.split(".");
	if (domains.length < 2) {
		return false;
	}
	for (i = 0; i < domains.length - 1; i++) {
		if (!(/^[a-zA-Z0-9\-]+$/).test(domains[i])) {
			return false;
		}
	}
	if(domains[domains.length-2].length < 2){
		return false;
	}
	if (!(/^[a-zA-Z]{2,}$/).test(domains[domains.length-1])){
		return false;
	}
	return true;
}

/*
* Returns true, if given string is valid domain name
* Valid urls:
*	127.0.0.1
*	http://127.0.0.1/index.html?query
*	google.com
*	http://www.google.com/search?q=Zapatec
* @param url - [string] value to test
*/
String.prototype.isURL = function(){
	var url = this.toString();
	if(typeof(url) != 'string'){
		return false;
	}
	var domain = url;
	var protocolSeparatorPos = url.indexOf("://");
	var domainSeparatorPos = url.indexOf("/", protocolSeparatorPos + 3);

	if(protocolSeparatorPos == 0){
		return false;
	}
	domain = url.substring(
		(protocolSeparatorPos > 0 ? protocolSeparatorPos + 3 : 0),
		(domainSeparatorPos > 0 ? domainSeparatorPos : url.length)
	);

	return domain.isDomain();
}

String.prototype.isEmail = function(){
	var email = this.toString();
	if(email == null){
		return false;
	}
	var atPos = email.indexOf("@");
	if(
		atPos < 1 ||
		email.indexOf(".", atPos) == -1
	){
		return false
	}
	var login = email.substring(0, atPos);
	var domain = email.substring(atPos + 1, email.length);

	// Regexp declarations
    var atom = "\[^\\s\\(\\)><@,;:\\\\\\\"\\.\\[\\]\]+";
    var word = "(" + atom + "|(\"[^\"]*\"))";
    var loginRE = new RegExp("^" + word + "(\\." + word + ")*$");

    for (i = 0; i < login.length; i++){
        if (login.charCodeAt(i) > 127){
            return false;
        }
    }

    if (!login.match(loginRE)){
        return false;
    }
    return domain.isDomain();
}

/*
* Returns true, if given string is valid credit card number(according to Luhn
* algorythm)
* @param cardNumber - [string] value to test
*/
String.prototype.isCreditCardNumber = function(){
	var cardNumber = this.toString();
	if(cardNumber == null){
		return false;
	}

	var cardDigits = cardNumber.replace(/\D/g, "");
	var parity = cardDigits.length % 2;
	var sum = 0;

	for(var ii = 0; ii < cardDigits.length; ii++){
		var digit = cardDigits.charAt(ii);

		if (ii % 2 == parity)
			digit = digit * 2;

		if (digit > 9)
			digit = digit - 9;

		sum += parseInt(digit);
	}

	return ((sum != 0) && (sum % 10 == 0))
}

/*
* Returns true if given string is valid date according to given format. Default format: "%m/%d/%y"
* @param str - [string] value to test
* @param format - [string] date format
*/
String.prototype.isDate = function(fmt){
	var str = this.toString();
	if(typeof fmt == "undefined" || fmt == null || fmt == ""){
		fmt = "%m/%d/%Y"
	}

	var separator = " ";
	var nums = fmt.split(separator)

	if (nums.length < 3){
		separator = "/"
		nums = fmt.split(separator)

		if (nums.length < 3){
			separator = "."
			nums = fmt.split(separator)

			if (nums.length < 3){
				separator = "-"
				nums = fmt.split(separator)

				if (nums.length < 3){
					separator = null;
				}
			}
		}
	}

	if(separator == null){
		return false;
	}

	var y = null;
	var m = null;
	var d = null;

	var a = str.split(separator);

	if(a.length != 3){
		return false;
	}

	var b = fmt.match(/%./g);

	var nlDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
	var lDays  = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

    for (var i = 0; i < a.length; ++i) {
		if (!a[i])
			continue;
		switch (b[i]) {
		    case "%d":
		    case "%e":
				d = parseInt(a[i], 10);
				if(d < 0 || d > 31)
					d = -1
				break;
		    case "%m":
				m = parseInt(a[i], 10) - 1;
				if(m > 11 || m < 0)
					m = -1;
				break;
		    case "%Y":
		    case "%y":
				y = parseInt(a[i], 10);
				(y < 100) && (y += (y > 29) ? 1900 : 2000);
				break;
		}
	}

	if (y == null || m == null || d == null || isNaN(y) || isNaN(m) || isNaN(d)){
		return false;
	}

	if(m != -1){
		if ((y % 4) == 0) {
			if ((y % 100) == 0 && (y % 400) != 0){
				if(d > nlDays[m]){
					d = -1;
				}
			}

			if(d > lDays[m]){
				d = -1;
			}
		} else {
			if(d > nlDays[m]){
				d = -1;
			}
		}
	}

	if (y != 0 && m != -1 && d != -1){
		return true;
	}

	return false;
}
//xxx xxx-xxxx
String.prototype.isUSPhone = function() {
	return this.toString().search(/^((\([1-9][0-9]{2}\) *)|([1-9][0-9]{2}[\-. ]?))(\d[ -]?){6}\d *(ex[t]? *[0-9]+)?$/) != -1;
}
//+x xxx xxx-xxxx
String.prototype.isIntPhone = function() {
	return this.toString().search(/^\+\d{1,3}[ -]\d{2,3}[ -](\d[ -]?){6}\d *(ex[t]? *[0-9]+)?$/) != -1;
}
String.prototype.isUSZip = function() {
	return this.toString().match(/(^\d{5}$)|(^\d{5}-\d{4}$)/) != -1;
}
// Upper case
String.prototype.UCFirst = function() {
  var str = this.toString();
  if (str.length > 0) return str.charAt(0).toUpperCase() + str.substr(1);
  return "";
}
// Upper case for all words
String.prototype.UCWords = function() {
  var str = this.toString();
  str = str.replace(/_/g," ");
  str_arr = str.split(" ");
  for (var i = 0; i< str_arr.length; i++)
    str_arr[i] = str_arr[i].UCFirst();
  return str_arr.join(" ");
}

function moveToCenter(obj) {
  if (typeof(obj) == "string") {
    obj = document.getElementById(obj);
  }
  var old_disp = obj.style.display;
  obj.style.display = "";
  var size = getWindowSize(); // window size
  var br = getPageScroll(); //scrolling
  var newX = Math.round((size.width - obj.offsetWidth) / 2) + br.x; 
  var newY = Math.round((size.height - obj.offsetHeight) / 2) + br.y;
  if (newX < 0) newX = 0;
  if (newY < 0) newY = 0;
  obj.style.position = "absolute";
  // alert("W:"+winW+' x '+winH+" C: "+w+' x '+h + " NEW: x="+newX+' y='+newY);
  obj.style.left =  newX + 'px';
  obj.style.top =  newY + 'px';
  obj.style.display = old_disp;
  // Fix
  var copy = obj.cloneNode(true);
  obj.parentNode.removeChild(obj);
  document.body.appendChild(copy);
}
function getWindowSize() {
  var iWidth = 0;
  var iHeight = 0;
  if (document.compatMode && document.compatMode == 'CSS1Compat') {
    // Standards-compliant mode
    if (window.opera) {
      iWidth = document.body.clientWidth || 0;
      iHeight = document.body.clientHeight || 0;
    } else {
      iWidth = document.documentElement.clientWidth || 0;
      iHeight = document.documentElement.clientHeight || 0;
    }
  } else {
    // Non standards-compliant mode
    iWidth = window.innerWidth || document.body.clientWidth || document.documentElement.clientWidth || 0;
    iHeight = window.innerHeight || document.body.clientHeight || document.documentElement.clientHeight || 0;
  }
  return {
    width: iWidth,
    height: iHeight
  };
};
function getPageScroll() {
  var s = {};
  s.y = window.pageYOffset || document.documentElement.scrollTop || (document.body ? document.body.scrollTop : 0) || 0;
  s.x = window.pageXOffset || document.documentElement.scrollLeft || (document.body ? document.body.scrollLeft : 0) || 0;
  return s;
};

var validator = new Validator();
